package com.younge.spring.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.younge.spring.api.param.MenuUpdateParam;
import com.younge.spring.api.result.MenuListResult;
import com.younge.spring.api.result.MenuMeta;
import com.younge.spring.repository.SysMenuRepository;
import com.younge.spring.repository.dao.SysMenu;
import com.younge.spring.service.util.SysMenuTreeBuilder;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

@Service
public class SysMenuService {
    private final SysMenuRepository sysMenuRepository;
    private final ObjectMapper mapper;

    public SysMenuService(SysMenuRepository sysMenuRepository, ObjectMapper mapper) {
        this.sysMenuRepository = sysMenuRepository;
        this.mapper = mapper;
    }

    public List<MenuListResult> getMenuList(String status, boolean notContainButton) {
        List<SysMenu> list;
        Sort sort = Sort.by("orderNum");
        if (StringUtils.hasText(status)) {
            list = sysMenuRepository.findByStatus(status, sort);
        } else {
            list = sysMenuRepository.findAll(sort);
        }
        return SysMenuTreeBuilder.buildTree(list, notContainButton);
    }

    public boolean isMenuNameExists(Long id, String name) {
        return sysMenuRepository.findByName(name).map(sysMenu -> !sysMenu.getId().equals(id)).orElse(false);
    }

    public boolean isMenuPathExists(Long id, String path) {
        return sysMenuRepository.findByPath(path).map(sysMenu -> !sysMenu.getId().equals(id)).orElse(false);
    }

    public String updateMenu(MenuUpdateParam param) {
        SysMenu menu = sysMenuRepository.findById(param.getId()).orElseThrow(() -> new RuntimeException("菜单不存在！"));
        MenuMeta meta = param.getMeta();
        menu.setName(param.getName());
        menu.setPath(param.getPath());
        menu.setComponent(param.getComponent());
        menu.setRedirect(param.getRedirect());
        menu.setStatus(param.getStatus());
        menu.setTitle(meta.getTitle());
        menu.setParentId(param.getPid());
        menu.setAuthCode(param.getAuthCode());
        menu.setOrderNum(meta.getOrder());
        menu.setRemark(param.getRemark());
        try {
            menu.setMate(mapper.writeValueAsString(meta));
        } catch (JsonProcessingException e) {
            throw new RuntimeException("数据异常！");
        }
        sysMenuRepository.save(menu);
        return "保存成功！";
    }

    public String createMenu(MenuUpdateParam param) {
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
        MenuMeta meta = param.getMeta();

        try {
            String metaStr = mapper.writeValueAsString(meta);
            SysMenu menu = mapper.readValue(mapper.writeValueAsString(param), SysMenu.class);
            menu.setMate(metaStr);
            menu.setTitle(meta.getTitle());
            menu.setParentId(param.getPid());
            menu.setOrderNum(meta.getOrder());
            sysMenuRepository.save(menu);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("创建失败，数据异常！");
        }
        return "菜单创建成功";
    }
}